/**
 * 
 */
package org.dei.perla.sys.core;

import java.io.BufferedReader;
import java.io.StringReader;

import org.dei.perla.parser.grammar.ParseException;
import org.dei.perla.parser.grammar.Parser;
import org.dei.perla.parser.statements.Query;
import org.dei.perla.utils.pipe.Pipe;

import sun.reflect.generics.reflectiveObjects.NotImplementedException;

/**
 * @author Romolo Camplani
 * La classe QueryParserStatic fornisce un metodo statico e sincronizzato per parsare le query.
 * Il risultato del parsing viene accodato in una pipe di uscita. Il risultato del parsing è true o false
 */
public class QueryParserStatic implements Pluggable<Object, Query>{

	private static boolean firstTime = true;
	private static Pipe<Query> pipe;
	private static QueryParserStatic singleton = null;
	
	private QueryParserStatic(){
	}
	
	public static QueryParserStatic getDefaultInstance(){
		if(singleton == null)
			singleton = new QueryParserStatic();
		return singleton;
	}
	
	public static synchronized Query parse(String query) {
		Query queryParsed = null;
		StringReader reader = new StringReader(query);
		BufferedReader bufferedReader = new BufferedReader(reader);
		if(firstTime){
			firstTime = false;
			new Parser(bufferedReader);
		}
		else{
			Parser.ReInit(bufferedReader);
		}
		try {
			queryParsed = Parser.StatementSequence();
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
		return queryParsed;
	}
	
	public static synchronized boolean isValid(String query){
		return QueryParserStatic.parse(query) == null;
	}

	public static void enqueueResult(Query query){
		pipe.enqueue(query);
	}
	
	@Override
	public Pipe<Object> getInputPipe() {
		throw new NotImplementedException();
	}

	@Override
	public Pipe<Query> getOutputPipe() {
		return pipe;
	}

	@Override
	public void setInputPipe(Pipe<Object> pipe) {
		throw new NotImplementedException();
	}

	@Override
	public void setOutputPipe(Pipe<Query> pipe) {
		QueryParserStatic.pipe = pipe;	
	}

}
